package com.gitee.fastmybatis.core.support.plugin;


import com.gitee.fastmybatis.core.util.ClassUtil;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;

import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.Properties;

/**
 * SQL美化插件
 */
@Intercepts({
        @Signature(type = ParameterHandler.class, method = "setParameters", args = {PreparedStatement.class})
})
public class SqlFormatterPlugin implements Interceptor {

    private static final Log LOG = LogFactory.getLog(SqlFormatterPlugin.class);

    private SqlFormatterHandler sqlFormatterHandler = new DefaultSqlFormatterHandler();


    public static Interceptor create() {
        SqlFormatterPlugin sqlFormatterPlugin = new SqlFormatterPlugin();
        Properties properties = new Properties();
        properties.put("enable", "true");
        sqlFormatterPlugin.setProperties(properties);
        return sqlFormatterPlugin;
    }

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        try {
            return invocation.proceed();
        } finally {
            sqlFormatterHandler.doPrintSql(invocation);
        }
    }


    @Override
    public void setProperties(Properties properties) {
        Objects.requireNonNull(properties, "properties can not null");
        String handlerClass = properties.getProperty("handlerClass");
        if (handlerClass != null) {
            try {
                Object obj = ClassUtil.newInstance(Class.forName(handlerClass));
                if (!(obj instanceof SqlFormatterHandler)) {
                    throw new RuntimeException(handlerClass + " should implements SqlFormatterHandler");
                }
                sqlFormatterHandler = (SqlFormatterHandler) obj;
            } catch (Exception e) {
                LOG.warn("Init SqlFormatterHandler error:" + e.getMessage());
                sqlFormatterHandler = new DefaultSqlFormatterHandler();
            }
        }
        sqlFormatterHandler.setProperties(properties);
    }

    public void setSqlFormatterHandler(SqlFormatterHandler sqlFormatterHandler) {
        this.sqlFormatterHandler = sqlFormatterHandler;
    }
}
